package com.sunther.document.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sunther.document.Enum.DictEnum;
import com.sunther.document.Enum.ExportHeaderEnum;
import com.sunther.document.dao.ProjectDao;
import com.sunther.document.entity.*;
import com.sunther.document.service.*;
import com.sunther.document.util.ExportExcelUtil;
import com.sunther.document.util.UserInfoUtil;
import com.sunther.idb.common.util.WebResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

import static com.sunther.document.Enum.DictEnum.ROLE_PROJECT_LEADER;

/**
 * @author csb
 * @description: TODO
 * @date 2023/5/16 10:16
 */
@Service
public class ProjectServiceImpl extends ServiceImpl<ProjectDao, ProjectEntity> implements ProjectService {

    @Autowired
    private ProjectDao projectDao;

    @Autowired
    private FileSystemMidService fileSystemMidService;

    @Autowired
    private FileSystemService fileSystemService;

    @Autowired
    private UserService userService;

    @Autowired
    private FileService fileService;

    @Autowired
    private ProjectHeaderService projectHeaderService;

    @Autowired
    private TermService termService;

    @Override
    public Map<String, String> getAllProjectNameMap() {
        List<ProjectEntity> list = list();
        Map<String, String> map = list.stream().collect(Collectors.toMap(ProjectEntity::getId, ProjectEntity::getName));
        return map;
    }

    /**
     * k:name  v:id
     * @return
     */
    @Override
    public Map<String, String> getAllProjectNameByNameMap() {
        List<ProjectEntity> list = list();
        Map<String, String> map = list.stream().collect(Collectors.toMap(ProjectEntity::getName, ProjectEntity::getId));
        return map;
    }

    @Override
    public List<ProjectEntity> listByKeyword(String keyword) {
        QueryWrapper<ProjectEntity> wrapper = new QueryWrapper<>();
        if (StrUtil.isNotBlank(keyword)){
            wrapper.like("name",keyword);
        }
        List<ProjectEntity> list = this.list(wrapper);
        getText(list);
        return list;
    }

    @Override
    public Page pageList(String keyword, Date startDate, Date endDate, int pageNumber, int pageSize, HttpServletRequest request) {
        Page page = new Page(pageNumber, pageSize);
        QueryWrapper<ProjectEntity> wrapper = new QueryWrapper<>();
        if (StrUtil.isNotBlank(keyword)){
            wrapper.like("name",keyword);
        }

        if (null != startDate) {
            wrapper.ge("start_time",startDate);
        }
        if (null != endDate) {
            wrapper.le("end_time",endDate);
        }

        //项目负责人只能看到自己所属项目
        Integer roleId = UserInfoUtil.getRoleId(request);
        Integer userId = UserInfoUtil.getUserId(request);
        if (Objects.equals(ROLE_PROJECT_LEADER.getCode(),roleId)){
            Set<String> projectIds = projectHeaderService.getProjectIdsByUserId(userId, DictEnum.PROJECT_USER_TYPE_HEADER.getCode());
            wrapper.in("id",projectIds);
        }
        //项目参与人只能看到所参与项目
        if (Objects.equals(DictEnum.ROLE_PROJECT_PARTICIPANTS.getCode(),roleId)){
            Set<String> projectIds = projectHeaderService.getProjectIdsByUserId(userId, DictEnum.PROJECT_USER_TYPE_JOIN.getCode());
            wrapper.in("id",projectIds);
        }
        wrapper.orderByDesc("update_time");
        Page pageList = projectDao.selectPage(page, wrapper);

        getText(pageList.getRecords());

        return pageList;
    }

    private void getText(List<ProjectEntity> records) {
        Map<String, String> systemNameByMap = fileSystemMidService.getAllSystemNameByMap();
        Set<String> ids = records.stream().map(ProjectEntity::getId).collect(Collectors.toSet());

        //获取项目对应负责人，参与人
        Map<String, Set<Integer>> headerMap = projectHeaderService.getUserIdsByUserType(ids,DictEnum.PROJECT_USER_TYPE_HEADER.getCode());
        Map<String, Set<Integer>> partsMap = projectHeaderService.getUserIdsByUserType(ids,DictEnum.PROJECT_USER_TYPE_JOIN.getCode());

        Set<Integer> headers = new HashSet<>();
        Set<Integer> parts = new HashSet<>();
        headerMap.forEach((k,v)->{ headers.addAll(v);
        });
        partsMap.forEach((k,v)->{ parts.addAll(v);
        });


        List<User> headerList = userService.getUserByIds(headers);
        List<User> partList = userService.getUserByIds(parts);
        records.stream().forEach(a -> {
            a.setProjectHead(headerMap.get(a.getId()));
            a.setProjectParticipants(partsMap.get(a.getId()));
            a.setSystemText(systemNameByMap.get(a.getSystemId()));
            //获取负责人和参与人信息
            if (null != a.getProjectHead()){
                StringBuilder strBuilder = new StringBuilder();
                a.getProjectHead().stream().forEach(b -> {
                    headerList.stream().forEach(c -> {
                        if (Objects.equals(b,c.getId().intValue())){
                            strBuilder.append(c.getNickName() +" "+ c.getTelephone() + " ,");
                        }
                    });
                });
                if(strBuilder.length() > 0){
                    strBuilder.deleteCharAt(strBuilder.length()-1);
                }
                a.setProjectHeadText(strBuilder.toString());
            }

            if (null != a.getProjectParticipants()){
                StringBuilder strBuilder2 = new StringBuilder();
                a.getProjectParticipants().stream().forEach(b -> {
                    partList.stream().forEach(c -> {
                        if (Objects.equals(b,c.getId().intValue())){
                            strBuilder2.append(c.getNickName() +" "+ c.getTelephone() + " ,");
                        }
                    });
                });
                if(strBuilder2.length() > 0){
                    strBuilder2.deleteCharAt(strBuilder2.length()-1);
                }
                a.setProjectParticipantsText(strBuilder2.toString());
            }

        });
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public WebResult saveOrUpdateProject(ProjectEntity projectEntity, HttpServletRequest request) {

        Integer userId = UserInfoUtil.getUserId(request);

        QueryWrapper<ProjectEntity> wrapper = new QueryWrapper<ProjectEntity>();
        wrapper.eq("name",projectEntity.getName());
        if (StrUtil.isNotBlank(projectEntity.getId())){
            wrapper.ne("id",projectEntity.getId());
        }
        long count = count(wrapper);
        if (count > 0) {
            return WebResult.failure("项目名称已存在");
        }

        if (projectEntity.getId() == null){
            projectEntity.init(String.valueOf(userId));
            String uuid = IdUtil.simpleUUID();
            projectEntity.setId(uuid);
        }else {
            projectEntity.modify(String.valueOf(userId));
        }

        // todo 项目取消负责人，参与人编辑
//        //先删除中间表
//        if (StrUtil.isNotBlank(projectEntity.getId())){
//            QueryWrapper<ProjectHeaderEntity> headerEntityQueryWrapper = new QueryWrapper<>();
//            headerEntityQueryWrapper.eq("project_id",projectEntity.getId());
//            projectHeaderService.remove(headerEntityQueryWrapper);
//        }
//
//        //保存中间表
//        Set<Integer> projectHead = projectEntity.getProjectHead();
//        Set<Integer> projectParticipants = projectEntity.getProjectParticipants();
//        ArrayList<ProjectHeaderEntity> headers = new ArrayList<>();
//        ArrayList<ProjectHeaderEntity> parts = new ArrayList<>();
//        ArrayList<ProjectHeaderEntity> lists = new ArrayList<>();
//        projectHead.stream().forEach(a -> {
//            ProjectHeaderEntity projectHeaderEntity = new ProjectHeaderEntity();
//            projectHeaderEntity.setUserId(a);
//            projectHeaderEntity.setProjectId(projectEntity.getId());
//            projectHeaderEntity.setUserType(DictEnum.PROJECT_USER_TYPE_HEADER.getCode());
//            headers.add(projectHeaderEntity);
//        });
//        projectParticipants.stream().forEach(a -> {
//            ProjectHeaderEntity projectHeaderEntity = new ProjectHeaderEntity();
//            projectHeaderEntity.setUserId(a);
//            projectHeaderEntity.setProjectId(projectEntity.getId());
//            projectHeaderEntity.setUserType(DictEnum.PROJECT_USER_TYPE_JOIN.getCode());
//            parts.add(projectHeaderEntity);
//        });
//        lists.addAll(headers);
//        lists.addAll(parts);
//        projectHeaderService.saveBatch(lists);

        saveOrUpdate(projectEntity);
        return WebResult.success("操作成功",projectEntity);
    }

    @Override
    public void export(String keyword, Date startDate, Date endDate, HttpServletRequest request, HttpServletResponse response) throws Exception {
        List<ProjectEntity> list = pageList(keyword, startDate, endDate, 1, 9999, request).getRecords();
        String title = "项目信息";
        String[] rowName = ExportHeaderEnum.PROJECT_ROW_NAME;
        List<Object[]> dataList = new ArrayList<>();

        int i = 0;
        for (ProjectEntity project : list) {
            Object[] obj = new Object[rowName.length];
            obj[0] = i++;
            obj[1] = project.getName();
            obj[2] = project.getUnitName();
            obj[3] = project.getProjectHeadText();

            obj[4] = DateUtil.format(project.getStartTime(),"yyyy-MM-dd");
            obj[5] = DateUtil.format(project.getEndTime(),"yyyy-MM-dd");
            dataList.add(obj);
        }

        ExportExcelUtil exportExcelUtil = new ExportExcelUtil(title, rowName, dataList, response);
        exportExcelUtil.export();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public WebResult delete(String id) {

        //有术语库关联不能删除
        QueryWrapper<TermEntity> wrap = new QueryWrapper<>();
        wrap.like("project_id",id);
        List<TermEntity> byProId = termService.list(wrap);
        if (null != byProId && byProId.size() > 0) {
            HashSet<String> hashSet = new HashSet<>();
            byProId.stream().forEach(a -> {
                hashSet.addAll(a.getProjectId());
            });
            if (hashSet.contains(id)){
                return WebResult.failure("该项目存在术语库所属项目中，请检查");
            }
        }

        ProjectEntity projectEntity = getById(id);

        //项目底下有文件不能删除
        QueryWrapper<FileEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("project_id",id);
        long count = fileService.count(wrapper);
        if (count > 0) {
            return WebResult.failure("请先清除文件再操作");
        }

        FileSystemMidEntity systemMidEntity = fileSystemMidService.getById(projectEntity.getSystemId());
        if (Objects.equals(DictEnum.SYSTEM_TYPE_DIY.getCode(),systemMidEntity.getSystemType())){
            //如果该项目是自定义体系，则一起删除
            //1、先删除详情表
            QueryWrapper<FileSystemEntity> wrapper1 = new QueryWrapper<>();
            wrapper1.eq("mid_id",systemMidEntity.getId());
            fileSystemService.remove(wrapper1);
            //2、再删除主表
            fileSystemMidService.removeById(systemMidEntity.getId());
        }

        //删除header中间表
        if (StrUtil.isNotBlank(projectEntity.getId())){
            QueryWrapper<ProjectHeaderEntity> headerEntityQueryWrapper = new QueryWrapper<>();
            headerEntityQueryWrapper.eq("project_id",projectEntity.getId());
            projectHeaderService.remove(headerEntityQueryWrapper);
        }

        //删除项目
        removeById(id);
        return WebResult.success("删除成功");
    }

    @Override
    public ProjectEntity dtl(String id) {
        ProjectEntity entity = getById(id);
        ArrayList<ProjectEntity> list = new ArrayList<>();
        list.add(entity);
        getText(list);
        return list.get(0);
    }
}
